package com.tianlh.zookeeper;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.leader.LeaderSelector;
import org.apache.curator.framework.recipes.leader.LeaderSelectorListenerAdapter;
import org.apache.curator.retry.ExponentialBackoffRetry;

/**
 * @author 黑子
 * @Date 2018/1/10 11:48
 */
public class ZkSelectMaster {

    /*
    * Master选举：
    * 其大体思路非常简单：
    * 选择一个根节点，例如／master_path，多台机器同时向该节点创建一个子节点: master_path/lock,
    * 利用ZooKeeper的特性，最终只有一台机器能够创建成功，成功的那台机器就作为Master。
    *
    * */

    static String path = "/master_path";
    static RetryPolicy retry = new ExponentialBackoffRetry(1000, 3);
    static CuratorFramework client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181")
        .namespace("master").sessionTimeoutMs(5000).retryPolicy(retry).build();

    public static void main(String[] args) throws InterruptedException {
        client.start();
        LeaderSelector selector = new LeaderSelector(client, path, new LeaderSelectorListenerAdapter() {

            /*
            * Curator会在竞争到Master后自动调用该方法，开发者可以在这个方陆中实现自己的业务逻辑。
            * 需要注意的是：
            * 一旦执行完takeleadership方法,Curator就会立即释放Master权利,然后重新开始新一轮的Master选举。
            * 当一个应用实例成为Master后,其他应用实例会进入等待,直到当前Master挂了或退出后才会开始选举新的Master。
            *
            * */
            @Override
            public void takeLeadership(CuratorFramework client) throws Exception {
                System.out.println("成为Master");
                Thread.sleep(5000);
                System.out.println("释放Master权利");
            }
        });
        selector.autoRequeue();
        selector.start();
        Thread.sleep(5000);
    }
}
